package cn.xiaopengstack.infrastructure.persistent.repository;

import cn.xiaopengstack.domain.activity.model.entity.GroupBuyActivityEntity;
import cn.xiaopengstack.domain.activity.model.entity.GroupBuyOrderDetailEntity;
import cn.xiaopengstack.domain.activity.model.entity.QueryInProgressGroupBuyOrderEntity;
import cn.xiaopengstack.domain.activity.model.entity.TeamStatisticEntity;
import cn.xiaopengstack.domain.activity.model.valobj.CrowTagDetailVO;
import cn.xiaopengstack.domain.activity.model.valobj.GroupBuyActivityDiscountVO;
import cn.xiaopengstack.domain.activity.model.valobj.GroupBuyActivityStatusEnum;
import cn.xiaopengstack.domain.activity.model.valobj.SkuVO;
import cn.xiaopengstack.domain.activity.repository.IActivityRepository;
import cn.xiaopengstack.domain.trade.model.valobj.GroupBuyOrderStatusEnum;
import cn.xiaopengstack.infrastructure.persistent.dao.*;
import cn.xiaopengstack.infrastructure.persistent.po.*;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author jiangyangang
 */
@Repository
public class ActivityRepository implements IActivityRepository {

    @Resource
    private IGroupBuyActivityDao groupBuyActivityDao;

    @Resource
    private IGroupBuyDiscountDao groupBuyDiscountDao;

    @Resource
    private SkuDao skuDao;

    @Resource
    private ScSkuActivityRefDao scSkuActivityRefDao;

    @Resource
    private ICrowdTagsDetailDao crowdTagsDetailDao;

    @Resource
    private IGroupBuyOrderDao groupBuyOrderDao;

    @Resource
    private IGroupBuyOrderListDao groupBuyOrderListDao;

    @Override
    public GroupBuyActivityDiscountVO queryGroupBuyActivityDiscountVO(String source, String channel) {
        ScSkuActivityRef scSkuActivityRefQuery = new ScSkuActivityRef();
        scSkuActivityRefQuery.setSource(source);
        scSkuActivityRefQuery.setChannel(channel);
        ScSkuActivityRef scSkuActivityRef = scSkuActivityRefDao.querySourceChannelActivityRef(scSkuActivityRefQuery);
        if (Objects.isNull(scSkuActivityRef)) {
            return null;
        }

        GroupBuyActivity groupBuyActivity = groupBuyActivityDao.queryByActivityId(scSkuActivityRef.getActivityId());
        if (Objects.isNull(groupBuyActivity)) {
            return null;
        }

        GroupBuyDiscount groupBuyDiscount = groupBuyDiscountDao.queryDiscountByDiscountId(groupBuyActivity.getDiscountId());
        if (Objects.isNull(groupBuyDiscount)) {
            return null;
        }

        GroupBuyActivityDiscountVO groupBuyActivityDiscountVO = GroupBuyActivityDiscountVO.builder()
                .activityId(groupBuyActivity.getActivityId())
                .activityName(groupBuyActivity.getActivityName())
                .groupType(groupBuyActivity.getGroupType())
                .endTime(groupBuyActivity.getEndTime().toInstant().toEpochMilli())
                .startTime(groupBuyActivity.getStartTime().toInstant().toEpochMilli())
                .tagId(groupBuyActivity.getTagId())
                .groupBuyDiscount(GroupBuyActivityDiscountVO.GroupBuyDiscount.builder()
                        .discountDesc(groupBuyDiscount.getDiscountDesc())
                        .discountName(groupBuyDiscount.getDiscountName())
                        .discountType(groupBuyDiscount.getDiscountType())
                        .marketExpr(groupBuyDiscount.getMarketExpr())
                        .marketPlan(groupBuyDiscount.getMarketPlan())
                        .tagId(groupBuyDiscount.getTagId())
                        .build())
                .target(groupBuyActivity.getTarget())
                .takeLimitCount(groupBuyActivity.getTakeLimitCount())
                .validTime(groupBuyActivity.getValidTime())
                .tagScope(groupBuyActivity.getTagScope())
                .status(groupBuyActivity.getStatus())
                .channel(groupBuyActivity.getChannel())
                .source(groupBuyActivity.getSource())
                .build();
        return groupBuyActivityDiscountVO;
    }

    @Override
    public SkuVO querySkuByGoodsId(String goodsId) {
        Sku sku = skuDao.querySkuByGoodsId(goodsId);
        return SkuVO.builder()
                .goodsId(sku.getGoodsId())
                .goodsName(sku.getGoodsName())
                .originalPrice(sku.getOriginalPrice())
                .build();
    }

    @Override
    public CrowTagDetailVO queryUserTagDetailVO(String userId, String tagId) {

        CrowdTagsDetail crowdTagsDetail = crowdTagsDetailDao.queryUserTagDetail(tagId, userId);
        if (Objects.isNull(crowdTagsDetail)) {
            return null;
        }

        return CrowTagDetailVO.builder()
                .tagId(crowdTagsDetail.getTagId())
                .userId(crowdTagsDetail.getUserId())
                .build();
    }

    @Override
    public GroupBuyActivityEntity queryGroupBuyActivityEntityByActivityId(Long activityId) {
        GroupBuyActivity groupBuyActivity = groupBuyActivityDao.queryByActivityId(activityId);

        GroupBuyActivityEntity groupBuyActivityEntity = GroupBuyActivityEntity.builder()
                .discountId(groupBuyActivity.getDiscountId())
                .endTime(groupBuyActivity.getEndTime().toInstant().toEpochMilli())
                .startTime(groupBuyActivity.getStartTime().toInstant().toEpochMilli())
                .activityId(groupBuyActivity.getActivityId())
                .source(groupBuyActivity.getSource())
                .channel(groupBuyActivity.getChannel())
                .activityName(groupBuyActivity.getActivityName())
                .target(groupBuyActivity.getTarget())
                .activityName(groupBuyActivity.getActivityName())
                .tagId(groupBuyActivity.getTagId())
                .tagScope(groupBuyActivity.getTagScope())
                .takeLimitCount(groupBuyActivity.getTakeLimitCount())
                .validTime(groupBuyActivity.getValidTime())
                .groupType(groupBuyActivity.getGroupType())
                .status(GroupBuyActivityStatusEnum.of(groupBuyActivity.getStatus()))
                .build();

        return groupBuyActivityEntity;
    }

    @Override
    public Integer queryOrderCountByActivityId(Long activityId, String userId) {
        return groupBuyActivityDao.queryOrderCountByActivityId(activityId, userId);
    }


    @Override
    public List<GroupBuyOrderDetailEntity> queryInProgressGroupOrderList(QueryInProgressGroupBuyOrderEntity queryInProgressGroupBuyOrderEntity) {
        // 查询队伍信息
        List<GroupBuyOrder> groupBuyOrders = groupBuyOrderDao.queryInProgressOrder(queryInProgressGroupBuyOrderEntity.getActivityId(),
                queryInProgressGroupBuyOrderEntity.getGoodsId(),
                queryInProgressGroupBuyOrderEntity.getSource(),
                queryInProgressGroupBuyOrderEntity.getChannel(),
                queryInProgressGroupBuyOrderEntity.getCount());

        if (CollectionUtils.isEmpty(groupBuyOrders)) {
            return Collections.emptyList();
        }

        List<String> teamIds = groupBuyOrders.stream().map(GroupBuyOrder::getTeamId).collect(Collectors.toList());

        // 查询组队详情
        List<GroupBuyOrderList> groupBuyOrderLists = groupBuyOrderListDao.queryInProgressOrderListsByTeamIds(teamIds);
        if (CollectionUtils.isEmpty(groupBuyOrderLists)) {
            return Collections.emptyList();
        }

        // 按队伍进行分组
        Map<String, List<GroupBuyOrderList>> groupBuyTeamList = groupBuyOrderLists.stream().collect(Collectors.groupingBy(GroupBuyOrderList::getTeamId));

        List<GroupBuyOrderDetailEntity> groupBuyOrderDetailEntityList = groupBuyOrders.stream().map((groupOrder) -> {

            // 获取组团订单的拼团详情
            List<GroupBuyOrderList> groupBuyOrderList = groupBuyTeamList.get(groupOrder.getTeamId());

            // 获取最先拼团的人
            String userId = groupBuyOrderList.stream().min(Comparator.comparing(GroupBuyOrderList::getCreateTime)).map(GroupBuyOrderList::getUserId).get();

            return GroupBuyOrderDetailEntity.builder()
                    .userId(userId)
                    .groupEndTime(groupOrder.getGroupEndTime())
                    .groupStartTime(groupOrder.getGroupStartTime())
                    .lockCount(groupOrder.getLockCount())
                    .completeCount(groupOrder.getCompleteCount())
                    .targetCount(groupOrder.getTargetCount())
                    .teamId(groupOrder.getTeamId())
                    .build();
        }).collect(Collectors.toList());

        return groupBuyOrderDetailEntityList;

    }

    @Override
    public List<GroupBuyOrderDetailEntity> queryInProgressGroupOrderListRandom(QueryInProgressGroupBuyOrderEntity queryInProgressGroupBuyOrderEntity) {
        return Collections.emptyList();
    }

    @Override
    public TeamStatisticEntity queryTeamStatistic(Long activityId, String goodsId) {
        // 可以放到redis进行统计
        List<GroupBuyOrder> groupBuyOrders = groupBuyOrderDao.queryAllGroupBuyOrders(activityId, goodsId);

        Integer allTeamCount = groupBuyOrders.size();

        Integer allTeamCompleteCount = (int) groupBuyOrders.stream().filter(order -> GroupBuyOrderStatusEnum.GROUP_COMPLETE.getStatus().equals(order.getStatus())).count();

        Integer allTeamUserCount = groupBuyOrders.stream().map(GroupBuyOrder::getLockCount).reduce(0, Integer::sum);

        return TeamStatisticEntity.builder()
                .allTeamCompleteCount(allTeamCompleteCount)
                .allTeamCount(allTeamCount)
                .allTeamUserCount(allTeamUserCount)
                .build();
    }
}
